import React,{ Component } from 'react'
import { LegionsProPageContainer,LegionsProModal } from 'legions-pro-design';
import { InstanceProForm } from 'legions-pro-design/es/LegionsProForm/interface';
import { InstanceProModal } from 'legions-pro-design/es/LegionsProModal/interface';
import { InstanceProTable } from 'legions-pro-design/es/LegionsProTable/interface';
import { Button,Steps,Row,Col,Spin,Icon,Card,message } from 'antd';
import { ProjectFormFields } from '../../models/form/projectFormFields';
import { bind,observer } from 'legions/store-react'
import ProjectStore,{ TStepCurr } from '../../stores/projectStore';
import { directiveSend,directiveReceive } from '../../utils/socket';
import { WrappedFormUtils } from 'legions-pro-design/es/interface/antd';
import { ProjectModules,ISendAst,IDirective } from '../../interface/project';
import { observable,action,computed,toJS,runInAction } from 'mobx';
import { observableViewModel,observablePromise } from 'legions/store-utils'
import TerminalView from '../../../common/components/terminal';
const serialize = require('serialize-javascript');
import '../../assets/css/project.less'
import { OperationEnum } from '../../constants/enum-data';
import get from 'lodash/get'
import unset from 'lodash/unset'
import {
    transformTableToekn,
    getExecutableScript,
    prettyPrint,
    transformTableParames,
    transformTableComponentCode,
    updateTableModelClassName,
} from '../../utils/codemod';
import { createTableListPage } from '../../utils/table-page-template';
import CanvasHomeEdit from '../canvas/canvasHome';
import { transformFuncToExeccodeast } from '../../utils/codemodCore';
import { cloneDeep } from 'lodash'
import { tranformCreateFormCommponent } from '../../utils/form-component-codemod';
import { FormPropertyAstUtils } from '../../utils/formPropertyUilts';
import { tranformCreateModel } from '../../utils/form-model-codemod';
import { FORM_PROPERTY_AST } from '../../constants/consts';
import { tablecodemod } from 'legions-gluttonous-ast';
import { GIT_URL } from '../../constants/system/gitConfig';
import upperFirst from 'lodash/upperFirst';
const { Step } = Steps;
interface IProps {
    store?: ProjectStore
}

@bind({ store: ProjectStore })
@observer
export default class ProjectEdit extends Component<IProps,{}> {
    formRef: InstanceProForm = null
    form: WrappedFormUtils = null
    modalRef: InstanceProModal = null
    queryPrams = {}
    constructor(props: IProps) {
        super(props)
        /*  directiveSend({}) */
        /* directiveReceive((result) => {
            if (result && result.state) {
                this.props.store.projectEditViewModel.updateLoadingState(result.state)
            }
        }) */
    }
    get getProjectConfig() {
        let projectFields: ProjectFormFields = null;
        if (this.props.store.createProjectFormRef) {
            projectFields = this.props.store.createProjectFormRef.viewModel.InputDataModel as ProjectFormFields;
        }
        else {
            projectFields = new ProjectFormFields();
        }
        const projectConfig = ProjectFormFields.formFieldsToData<ProjectFormFields,ProjectModules.ISendData>(ProjectFormFields,projectFields);
        const gitSrc = GIT_URL.replace('user',projectConfig.gitUserName).replace('pwd',projectConfig.gitPwd).replace('modules',projectConfig.modulesSystem[0]);
        projectConfig.gitSrc = gitSrc;
        let modulesSystem: string[] = [];
        let projectSrc = projectConfig.projectSrc;
        if (Object.prototype.toString.call(projectConfig.modulesSystem) === '[object Array]') {
            modulesSystem = [...projectConfig.modulesSystem];
        }
        if (modulesSystem.length === 3) {
            projectSrc = `${projectSrc}/packages/${modulesSystem[1]}`;
            projectConfig.modulesSystem = modulesSystem[2];
            projectConfig.projectSrc = projectSrc;
        }
        return projectConfig;
    }
    get getSendData() {
        const QueryPropertyApp = this.props.store.context.listPagePropertyApp.context.QueryPropertyApp;
        const TablePropertyApp = this.props.store.context.listPagePropertyApp.context.TablePropertyApp;
        const projectCommonApp = this.props.store.context.projectCommonApp;
        const query = QueryPropertyApp.queryComponentRef.viewModel.computedQuery;
        const projectConfig = this.getProjectConfig;
        TablePropertyApp.viewModel.tableBaseConfigCode.columns = TablePropertyApp.viewModel.tableColumns;
        const sendData: ISendAst = {
            ast: {
                queryAst: query,
                selectAutoQueryList: projectCommonApp.computedConditionSelectOpt,
                tableDataSourceAst: TablePropertyApp.viewModel.tableDataSourceCode,
                tableBaseConfigAst: TablePropertyApp.viewModel.tableBaseConfigCode,
            },
            branch: projectConfig.branch,
            gitSrc: projectConfig.gitSrc,
            templateType: this.props.store.projectEditViewModel.currentTemplatePage,
            projectSrc: projectConfig.projectSrc,
            modulesSystem: projectConfig.modulesSystem,
            gitUserName: projectConfig.gitUserName,
            componentName: projectConfig.componentName || 'orderPageList',
        }
        return sendData;
    }
    /** 表单model数据转换成代码字符串 */
    tranformCreateModelToString(componentName: string) {
        const formPropertyApp = this.props.store.context.formPropertyApp;
        //@ts-ignore
        return tranformCreateModel(formPropertyApp.propertyFormationVM.propertyData,`${componentName}FormFields`,FORM_PROPERTY_AST)
    }
    /** 表单数据转换成表单组件代码 */
    tranformCreateFormCommponentToString(componentName: string) {
        const formPropertyApp = this.props.store.context.formPropertyApp;
        const computedControlsSort = formPropertyApp.formPropertyDraggerRef.localViewModel.computedControlsSort;
        const controls = formPropertyApp.formPropertyDraggerRef.viewModel.computedAllFormFields;
        const controlsSortUid: string[] = [];
        const controlsSortName: string[] = [];

        computedControlsSort.map((item) => {
            const newItems = controls.find((w) => w.iAntdProps.name === item);
            if (newItems) {
                controlsSortUid.push(newItems.iAntdProps.uuid);
            }
        });
        controlsSortUid.map((item) => {
            const newItems = formPropertyApp.propertyFormationVM.computedElementUidMap.find((w) => w.uuid === item);
            if (newItems) {
                controlsSortName.push(newItems.name);
            }
        })
        return tranformCreateFormCommponent({
            //@ts-ignore
            propertyData: formPropertyApp.propertyFormationVM.propertyData,
            controlsElementSort: controlsSortName,
        },{
            componentName: componentName,
            //@ts-ignore
            group: [...formPropertyApp.propertyFormationVM.group],
            size: formPropertyApp.propertyFormationVM.size,
            layout: formPropertyApp.propertyFormationVM.layout,
        },FORM_PROPERTY_AST);
    }
    createFormCode() {
        const formPropertyApp = this.props.store.context.formPropertyApp;
        const { propertyData } = formPropertyApp.propertyFormationVM;
        const keys = propertyData.keys();
        const projectConfig = this.getProjectConfig;
        const config: { name: string }[] = [];
        for (let key of keys) {
            const model = FormPropertyAstUtils.create(propertyData.get(key).componentType,propertyData.get(key).propertyValue)
            config.push({ name: get(model,'name') })
        }
        if (config.every((item) => item.name)) {
            return {
                modelCode: this.tranformCreateModelToString(projectConfig.componentName || ''),
                componentCode: this.tranformCreateFormCommponentToString(projectConfig.componentName || 'ProFormDemo'),
            }
        }
        return {
            modelCode: '',
            componentCode: '',
        }
    }

    createTableCode() {
        const sendData = this.getSendData;
        const TablePropertyApp = this.props.store.context.listPagePropertyApp.context.TablePropertyApp;
        if (TablePropertyApp.viewModel.tableDataSourceCode === null) {
            message.warning('请设置表格属性')
            return
        }
        const code = createTableListPage(sendData);
        //@ts-ignore
        const tableCode = transformTableComponentCode(code.tablePageCode,TablePropertyApp.viewModel.operationConfigCode,sendData);
        return {
            modelCode: code.tableModelCode,
            componentCode: tableCode,
        }

    }
    createCode() {
        const currentTemplatePage = this.props.store.projectEditViewModel.currentTemplatePage;
        if (currentTemplatePage === 'listPage') {
            return this.createTableCode();
        }
        else if (currentTemplatePage === 'formPage') {
            return this.createFormCode();
        }
    }
    /**
     * 生成代码
     *
     * @memberof ProjectEdit
     */
    handleCreatePage = () => {
        if (this.props.store.projectEditViewModel.stepCurr !== 1) {
            message.warning('请先填写项目信息...');
        }
        else {
            if (this.props.store.projectEditViewModel.currentTemplatePage === 'formPage') {
                const code = this.createFormCode();
                if (code.componentCode && code.modelCode) {
                    directiveSend({
                        generatedCode: {
                            sendData: {
                                ...this.getSendData,
                                formPageCode: {
                                    modelCode: code.modelCode,
                                    formComponentCode: code.componentCode,
                                }
                            },
                        },
                    })
                    this.props.store.projectEditViewModel.operation = OperationEnum.save;
                    this.modalRef.viewModel.visible = true;
                    this.modalRef.viewModel.title = '页面执行';
                }
            }
            else if (this.props.store.projectEditViewModel.currentTemplatePage === 'listPage') {
                const code = this.createTableCode();
                if (code.componentCode && code.modelCode) { 
                    this.props.store.projectEditViewModel.operation = OperationEnum.save;
                    this.modalRef.viewModel.visible = true;
                    this.modalRef.viewModel.title = '页面执行';
                    this.modalRef.viewModel.okText = '生成';
                    const modelCode = updateTableModelClassName(code.modelCode,`${upperFirst(this.getProjectConfig.componentName)}ContainerEntity`)
                    code.modelCode = modelCode;
                    directiveSend({
                        generatedCode: {
                            sendData: {
                                ...this.getSendData,
                                tablePageListCode: {
                                    tableHomePageCode:code.componentCode ,
                                    tableModelCode: code.modelCode,
                                }
                            },
                        },
                    })
                }
            }
            else {
                message.warning('请先选择需要生成的模板');
            }
        }

    }
    onTransfrom = (value: IDirective['initProject']) => {
        return value.responseData.replace('client:','').replace(/state:error[\r\n]/g,'').replace('state:error','').replace('state:pending↵','')
            .replace('state:pending','').replace('state:complete↵','').replace('state:complete↵','').replace('state:complete','').replace('↵','')
    }
    onReceive = (resmessage: IDirective['initProject']) => {
        if (resmessage && resmessage.state) {
            this.props.store.projectEditViewModel.updateLoadingState(resmessage.state)
        }
    }
    onChangeStep = (step: TStepCurr) => {
        if (this.props.store.projectEditViewModel.stepCurr === step) {
            return;
        }
        if (this.props.store.projectEditViewModel.computedLoad === 'complete') {
            this.props.store.projectEditViewModel.stepCurr = step;
        } else {
            message.warning('请先填写项目信息')
        }
    }
    onPreview = () => {
        const tableData = this.props.store.context.listPagePropertyApp.context.TablePropertyApp;
        const receiveValue = 'this.props.store.context.listPagePropertyApp.context.TablePropertyApp';
        const tableDataSourceCode = tableData.viewModel.tableDataSourceCode;
        runInAction(() => {
            if (tableDataSourceCode && tableDataSourceCode.apiUrl) {
                this.props.store.projectEditViewModel.setSketchpadPreviewMode();
                const token = transformTableToekn(tableData.viewModel.tableDataSourceCode.token)
                // tslint:disable-next-line: no-eval
                eval(getExecutableScript(token,this))
                const execcodeast = (name: string) => {
                    const code = transformFuncToExeccodeast(tableData.viewModel.tableDataSourceCode[name],{
                        propertyName: name,
                        receiveValue: `${receiveValue}.viewModel.paramesExeccodeast`,
                    });
                    eval(getExecutableScript(code,this));
                    return tableData.viewModel.paramesExeccodeast[name]
                }
                const execcodeExpressionAst = () => {
                    const code = tablecodemod.tranformObjectExpressionToExec(tableData.viewModel.tableDataSourceCode.options,`${receiveValue}.viewModel.paramesExeccodeast`);
                    eval(getExecutableScript(code,this));
                    return tableData.viewModel.paramesExeccodeast
                }
                const autoQuery = {
                    params: execcodeast('params'),

                    token: this.props.store.projectEditViewModel.token,
                    ApiUrl: tableData.viewModel.tableDataSourceCode.apiUrl,
                    options: execcodeExpressionAst(),
                    // @ts-ignore
                    method: tableData.viewModel.tableDataSourceCode.method,
                    transform: execcodeast('transform'),
                    mappingEntity: execcodeast('mappingEntity'),
                }
                tableData.tablePreviewRef && tableData.tablePreviewRef.localViewModel.dispatchRequest(autoQuery,{
                    pageIndex: tableData.tablePreviewRef.viewModel.pageIndex,
                    pageSize: tableData.tablePreviewRef.viewModel.pageSize,
                    isShowLoading: true,
                })

            } else {
                message.warning('请先填写表格配置信息')
            }
        })

    }
    renderStepIcon(type: string,step: TStepCurr) {
        return <Icon type={type} style={{ cursor: 'pointer' }} onClick={this.onChangeStep.bind(this,step)} />
    }
    render() {
        return (
            <React.Fragment>
                {
                    this.props.store.projectEditViewModel.stepCurr === 1 &&
                    <CanvasHomeEdit
                        onCreatePageCode={this.handleCreatePage}
                        onCreateCode={this.createCode.bind(this)}
                        onPreview={this.onPreview}></CanvasHomeEdit>
                }
                {/* ====生成页面代码界面start===== */}
                <LegionsProModal
                    okText="生成"
                    onReady={(value) => {
                        this.modalRef = value;
                        this.modalRef.viewModel.width = 300 * 3;
                    }}>
                    {this.props.store.projectEditViewModel.operation === OperationEnum.save && <TerminalView
                        style={{ marginTop: '10px' }}
                        onTransfrom={this.onTransfrom}
                        onSocketReceive={directiveReceive} onReceive={this.onReceive}></TerminalView>}
                </LegionsProModal>
                {/* ====生成页面代码界面end===== */}
            </React.Fragment>
        )
    }
}